// 数据劫持
class Observer {
  constructor(data) {
    this.observe(data());
  }

  observe(data) {
    if (!data || typeof data !== 'object') {
      return;
    }
    /**
     * console.log(data);
     * {
     *   message: "Hello World", 
     *   color: color: {red: "#123334", orange: "#333344"}
     * }
     */

    // console.log(Object.keys(data));
    //["message", "color"]
    Object.keys(data).forEach(key => {
      //defineReactive(数据,键名,键值)自定义响应式
      this.defineReactive(data, key, data[key]);
      //递归嵌套的数据
      this.observe(data[key]);
    });
  }

  defineReactive(obj, key, value) {
    let _this = this;

    let dep = new Dep();

    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get() {
        //Dep.target => Watcher实例对象
        Dep.target && dep.addSub(Dep.target);
        return value;
      },
      set(newValue) {
        if (newValue !== value) {
          _this.observe(newValue);
          value = newValue;
          //数据发生更改时通知订阅者
          dep.notify();
        }
      }
    });
  }
}

//发布与订阅
class Dep {
  constructor() {
    //订阅者数组
    this.subs = [];
  }

  //观察者
  addSub(watcher) {
    this.subs.push(watcher);
  }

  //通知
  notify() {
    this.subs.forEach(watcher => watcher.updata());
  }
}